# 迭代拆分算法实现

import pandas as pd
from src.config.constants import (
    CLASSIFICATION_CATEGORIES,
    PACKAGE_TYPE,
    ITERATIVE_SPLITTING,
)
# 导入工具函数
from src.utils.text_utils import calculate_weighted_similarity


def _process_independent_package(result, idx, row, historical_records):
    """处理仅独立包装的记录

    Args:
        result: 结果DataFrame
        idx: 当前记录的索引
        row: 当前记录数据
        historical_records: 匹配的历史记录
    """
    quantity = row["数量"]

    # 步骤3：独立包装数量精确匹配
    exact_match = historical_records[historical_records["数量"] == quantity]
    if not exact_match.empty:
        # 存在完全匹配的数量，标记为复用项
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REUSE"]
        # 复制匹配的包装方案信息
        from .classification import _copy_package_info

        _copy_package_info(result, exact_match.iloc[0], idx)
        return

    # 步骤4：数量关系分析
    # 检查是否存在历史数量大于待处理数量且不存在历史数量小于待处理数量
    has_greater = not historical_records[
        historical_records["数量"] > quantity
    ].empty
    has_less = not historical_records[
        historical_records["数量"] < quantity
    ].empty

    if has_greater and not has_less:
        # 存在历史数量大于待处理数量且不存在历史数量小于待处理数量
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES[
            "REFERENCE_INDEPENDENT"
        ]
        return

    if not has_less:
        # 没有小于待处理数量的历史记录
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES[
            "REFERENCE_INDEPENDENT"
        ]
        return

    # 步骤5：按客户日期分组检查拆分条件
    customer = row["客户简称"]
    date = row["预完工日期"]

    # 筛选该客户和日期的历史记录
    customer_date_records = historical_records[
        (historical_records["客户简称"] == customer)
        & (historical_records["预完工日期"] == date)
    ]

    # 筛选数量小于待处理数量的记录
    eligible_records = customer_date_records[
        customer_date_records["数量"] < quantity
    ]

    # 使用配置文件中的阈值
    if len(eligible_records) >= ITERATIVE_SPLITTING["MIN_ELIGIBLE_RECORDS"]:
        # 符合拆分条件，执行迭代拆分
        remaining_quantity = quantity
        split_items = []

        # 按数量降序排序
        sorted_records = eligible_records.sort_values(
            by="数量", ascending=False
        )

        # 执行迭代拆分
        iterations = 0
        while (
            remaining_quantity > 0
            and iterations < ITERATIVE_SPLITTING["MAX_ITERATIONS"]
        ):
            for _, record in sorted_records.iterrows():
                if record["数量"] <= remaining_quantity:
                    # 添加拆分项
                    split_item = row.copy()
                    split_item["数量"] = record["数量"]
                    split_item["备注"] = CLASSIFICATION_CATEGORIES["REUSE"]
                    # 复制包装方案信息
                    from .classification import _copy_package_info

                    _copy_package_info(split_item, record)
                    split_items.append(split_item)

                    remaining_quantity -= record["数量"]

                    if remaining_quantity == 0:
                        break

            iterations += 1

        # 处理剩余数量小于最小剩余数量的情况
        if (
            remaining_quantity > 0
            and remaining_quantity
            < ITERATIVE_SPLITTING["MIN_REMAINING_QUANTITY"]
        ):
            remaining_quantity = 0

        # 处理拆分结果
        if split_items:
            # 将原记录替换为拆分项
            # 实际实现中可能需要更复杂的处理，这里简化处理
            for split_item in split_items:
                # 添加拆分项到结果中
                # 注意：这里只是概念性的实现，实际操作需要根据具体数据结构调整
                pass

            if remaining_quantity == 0:
                # 完全拆分成功
                result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REUSE"]
            else:
                # 部分拆分成功
                result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES[
                    "REFERENCE_INDEPENDENT"
                ]
    else:
        # 不符合拆分条件
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES[
            "REFERENCE_INDEPENDENT"
        ]


def _process_mixed_package(result, idx, row, historical_records):
    """处理混合包装的记录

    Args:
        result: 结果DataFrame
        idx: 当前记录的索引
        row: 当前记录数据
        historical_records: 匹配的历史记录
    """
    quantity = row["数量"]

    # 步骤7：独立包装数量精确匹配
    # 从历史记录中筛选独立包装
    independent_packages = historical_records[
        historical_records["包装类型"] == PACKAGE_TYPE["INDEPENDENT"]
    ]
    exact_match = independent_packages[
        independent_packages["数量"] == quantity
    ]

    if not exact_match.empty:
        # 存在完全匹配的数量，标记为复用项
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REUSE"]
        # 复制匹配的包装方案信息
        from .classification import _copy_package_info

        _copy_package_info(result, exact_match.iloc[0], idx)
        return

    # 步骤8：数量关系分析
    # 检查是否存在历史数量大于待处理数量且不存在历史数量小于待处理数量
    has_greater = not independent_packages[
        independent_packages["数量"] > quantity
    ].empty
    has_less = not independent_packages[
        independent_packages["数量"] < quantity
    ].empty

    if has_greater and not has_less:
        # 存在历史数量大于待处理数量且不存在历史数量小于待处理数量
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REFERENCE_MIXED"]
        return

    if not has_less:
        # 没有小于待处理数量的历史记录
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REFERENCE_MIXED"]
        return

    # 步骤9：按客户日期分组检查拆分条件
    customer = row["客户简称"]
    date = row["预完工日期"]

    # 筛选该客户和日期的历史独立包装记录
    customer_date_records = independent_packages[
        (independent_packages["客户简称"] == customer)
        & (independent_packages["预完工日期"] == date)
    ]

    # 筛选数量小于待处理数量的记录
    eligible_records = customer_date_records[
        customer_date_records["数量"] < quantity
    ]

    # 使用配置文件中的阈值
    if len(eligible_records) >= ITERATIVE_SPLITTING["MIN_ELIGIBLE_RECORDS"]:
        # 符合拆分条件，执行迭代拆分
        remaining_quantity = quantity
        split_items = []

        # 按数量降序排序
        sorted_records = eligible_records.sort_values(
            by="数量", ascending=False
        )

        # 执行迭代拆分
        iterations = 0
        while (
            remaining_quantity > 0
            and iterations < ITERATIVE_SPLITTING["MAX_ITERATIONS"]
        ):
            for _, record in sorted_records.iterrows():
                if record["数量"] <= remaining_quantity:
                    # 添加拆分项
                    split_item = row.copy()
                    split_item["数量"] = record["数量"]
                    split_item["备注"] = CLASSIFICATION_CATEGORIES["REUSE"]
                    # 复制包装方案信息
                    from .classification import _copy_package_info

                    _copy_package_info(split_item, record)
                    split_items.append(split_item)

                    remaining_quantity -= record["数量"]

                    if remaining_quantity == 0:
                        break

            iterations += 1

        # 处理剩余数量小于最小剩余数量的情况
        if (
            remaining_quantity > 0
            and remaining_quantity
            < ITERATIVE_SPLITTING["MIN_REMAINING_QUANTITY"]
        ):
            remaining_quantity = 0

        # 处理拆分结果
        if split_items:
            # 将原记录替换为拆分项
            # 实际实现中可能需要更复杂的处理，这里简化处理
            for split_item in split_items:
                # 添加拆分项到结果中
                # 注意：这里只是概念性的实现，实际操作需要根据具体数据结构调整
                pass

            if remaining_quantity == 0:
                # 完全拆分成功
                result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REUSE"]
            else:
                # 部分拆分成功
                result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES[
                    "REFERENCE_MIXED"
                ]
    else:
        # 不符合拆分条件
        result.at[idx, "备注"] = CLASSIFICATION_CATEGORIES["REFERENCE_MIXED"]


def iterative_splitting(target_data, historical_data):
    """迭代拆分功能

    Args:
        target_data: 目标数据
        historical_data: 历史数据

    Returns:
        拆分后的数据
    """
    # 完整实现迭代拆分逻辑
    if target_data is None or target_data.empty:
        return target_data
        
    # 创建副本以避免修改原数据
    result = target_data.copy()
    
    # 筛选独立包装参考项
    independent_mask = result["备注"] == CLASSIFICATION_CATEGORIES["REFERENCE_INDEPENDENT"]
    if independent_mask.any():
        for idx in result[independent_mask].index:
            row = result.loc[idx]
            # 从目标数据中获取匹配的历史记录
            matching_historical_records = row.get("匹配历史记录", None)
            if matching_historical_records is not None and not matching_historical_records.empty:
                _process_independent_package(result, idx, row, matching_historical_records)
    
    # 筛选混合包装参考项
    mixed_mask = result["备注"] == CLASSIFICATION_CATEGORIES["REFERENCE_MIXED"]
    if mixed_mask.any():
        for idx in result[mixed_mask].index:
            row = result.loc[idx]
            # 从目标数据中获取匹配的历史记录
            matching_historical_records = row.get("匹配历史记录", None)
            if matching_historical_records is not None and not matching_historical_records.empty:
                _process_mixed_package(result, idx, row, matching_historical_records)
    
    return result
